package stone926.mods.more_enchantments.util;

import net.minecraft.entity.Entity;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;

import java.util.function.Predicate;

import static stone926.mods.more_enchantments.MoreEnchantmentsMod.FLOWER_ACTION_REPORT;

public final class Logger<T> {

  private final boolean shouldLog;
  private final org.apache.logging.log4j.Logger LOGGER;

  public Logger(ServerWorld world, org.apache.logging.log4j.Logger logger) {
    this.shouldLog = world.getGameRules().getBoolean(FLOWER_ACTION_REPORT);
    LOGGER = logger;
  }

  public Logger(ServerWorld world, org.apache.logging.log4j.Logger logger, Predicate<T> shouldLogPredicate, T predicateArg) {
    this.shouldLog = shouldLogPredicate.test(predicateArg);
    LOGGER = logger;
  }

  public Logger(ServerWorld world, org.apache.logging.log4j.Logger logger, boolean shouldLog) {
    this.shouldLog = shouldLog;
    LOGGER = logger;
  }

  public static StringBuilder getBlockDesc(BlockPos pos, String blockName) {
    int bx = pos.getX();
    int by = pos.getY();
    int bz = pos.getZ();
    return new StringBuilder()
      .append(blockName)
      .append("[")
      .append("x=").append(bx).append(",")
      .append("y=").append(by).append(",")
      .append("z=").append(bz)
      .append("]");
  }

  public static StringBuilder getEntityDesc(Entity entity) {
    double x = entity.getX();
    double y = entity.getY();
    double z = entity.getZ();
    return new StringBuilder()
      .append(entity.getName().getString())
      .append("[")
      .append("x=").append(String.format("%.1f", x)).append(",")
      .append("y=").append(String.format("%.1f", y)).append(",")
      .append("z=").append(String.format("%.1f", z))
      .append("]");
  }

  public static StringBuilder getEffectDesc(StatusEffectInstance instance) {
    return new StringBuilder()
      .append(instance.getEffectType().getName().getString())
      .append("[")
      .append("amplifier=").append(instance.getAmplifier())
      .append("]");
  }

  public boolean shouldLog() {
    return shouldLog;
  }

  public org.apache.logging.log4j.Logger getLog4jLogger() {
    return LOGGER;
  }

  public void logBegin(Object msg) {
    l(() -> {
      LOGGER.info("{{{   [[begin]]");
      logContent(msg);
    });
  }

  public void logEnd(Object msg, boolean hasBody) {
    l(() -> {
      if (hasBody) {logContent(msg);}
      LOGGER.info("}}}   [[end]]");
      LOGGER.info("————————————————————————————————————————————————————————————");
    });
  }

  public void logContent(Object msg) {
    l(() -> LOGGER.info("  ----  " + msg));
  }

  public void log(Object msg) {
    l(() -> LOGGER.info(msg));
  }

  private void l(Function function) {
    if (shouldLog()) function.run();
  }


  @FunctionalInterface
  public interface Function {

    void run();

  }

}

